perm filename SAMPLE.DOC[TEX,DEK]1 blob
sn#419321 filedate 1979-02-17 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00009 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00003 00002 {{\text This is a sample ``style-sheet'' to illustrate the recommended conventions
C00007 00003 {{\text Here are samples of integer definitions that will cause UNDOC to make
C00011 00004 {{\text It isn't clear exactly what types should be declared, but the tentative
C00013 00005 {{\text The \\{get_next} procedure acts as \TEX's eyes and mouth, as they read and
C00017 00006 { Input from external file,
C00020 00007 { Scan a control ... } =
C00023 00008 { Move to next line of file, or
C00031 00009 { Input from token list, \goto\ \{do_get_next} if end of list
C00038 ENDMK
C⊗;
{{\text This is a sample ``style-sheet'' to illustrate the recommended conventions
desirable for \TEX\ documentation. Explanatory material that has been enclosed
in $\{\{$ and $\}\}$ (like the explanatory material you are now reading)
should be acceptable \TEX\ input; it will be removed from the corresponding
PASCAL program produced by UNDOC, but it will be typeset in place as part
of the printed documentation produced by TEXDOC.
Documentation files like this one have the suffix \.{.DOC}; the UNDOC program
converts them into files with suffix \.{.PAS}, and the TEXDOC program converts them
into files with suffix \.{.TEX}.
The program segment below is the \\{get_next} procedure, recoded from page 10 of
the original SAIL version in file \.{TEXSYN.SAI}. The program conventions have
changed slightly, mainly because \\{inbuf} and \\{curbuf} now are simply
pointers to an ascii array \\{instack}, not variables of type {\bf string}.
Some of the names have changed too; for example, \\{align_insert} has been
substituted for the less appropriate name \\{aligndelim}. The variable
\\{page_warning} is now of type (\\{OK}, \\{def_of}, \\{use_of}). And so on.}}
{{\text Here are samples of integer definitions that will cause UNDOC to make
corresponding substitutions in the program text:}}
{ escape } := 0 {{ escape delimiter (\.{``} in TEX manual) }}
{ lbrace } := 1 {{ begin block symbol ( \.{\char'173} ) }}
{ rbrace } := 2 {{ end block symbol ( \.{\char'176} ) }}
{ mathbr } := 3 {{ math break ( \.{\char'44} ) }}
{ tabmrk } := 4 {{ tab mark ( \.{\char'26} ) }}
{ carret } := 5 {{ carriage return or comment ( \.{\char'45} ), \.{``cr} }}
{ macprm } := 6 {{ macro parameter ( \.{\char'43} ) }}
{ supmrk } := 7 {{ superscript ( \.{\char'136} ) }}
{ submrk } := 8 {{ subscript ( \.{\char'175} ) }}
{ ignore } := 9 {{ characters to ignore }}
{ spacer } := 10 {{ characters treated as blank space }}
{ letter } := 11 {{ characters treated as letters }}
{ otherchar } := 12 {{ none of the above character types }}
{ parend } := 13 {{ end of paragraph }}
{ match } := 14 {{ macro parameter matching }}
{ charcodes } := 13 {{ number of distinct character types }}
{ tokenlist } := 0 {{ scanning a token list }}
{ midline } := 1 {{ scanning a line of characters }}
{ skipblanks } := midline+charcodes {{ like \\{midline} but ignoring blanks }}
{ newline } := skipblanks+charcodes {{ beginning a new line of characters }}
{ line+feed } := '12 {{ end of line in ascii input file }}
{ form_feed } := '14 {{ end of page in ascii input file }}
{ carriage_return } := '15 {{ precedes end of line in ascii input file }}
{ hashsize } := 353 {{ hashtable size, must be prime and $<\\{charsize}-127$ }}
{ texpars } := 10 {{ number of distinct parameters settable by \.{``chpar} }}
{ eqtbsize } := hashsize+128+128+texpars {{ size of table for current values }}
{ chartype_offset } := hashsize+128 {{ location of character type in \\{eqtb} }}
{ tracing_offset } := hashsize+268 {{ location of tracing control in \\{eqtb} }}
{ param } := 0 {{ \\{recovery} code for parameters }}
{ ujlist } := 1 {{ \\{recovery} code for $u↓j$ lists in alignments }}
{ vjlist } := 2 {{ \\{recovery} code for $v↓j$ lists in alignments }}
{ inserted } := 3 {{ \\{recovery} code for an inserted token list }}
{ do_get_next } := 1 {{ label in \\{get_next} procedure }}
{ end_get_next } := 2 {{ label in \\{get_next} procedure }}
{ inner_switch } := 3 {{ label in \\{get_next} procedure }}
{{\text It isn't clear exactly what types should be declared, but the tentative
types listed below appear in this example. The roles of \\{loc} and \\{recovery}
have been reversed for character files, so that \\{loc} is always of type
\\{integer} and \\{recovery} is always of type \\{inflnk}. The \\{info} field
of \\{recovery} is now set to positive values in all cases, instead of using
conventions like $-l$, etc.}}
type inflnk = packed record info: 0..131071; link: 0..32767 end;
token = packed record cmd: 0..15; chr: 0..1023 end;
toklnk = packed record tok: token; link: 0..32767 end;
eqtbval = packed record idcmd: 0..127; idlev: 0..31; idlen: 0..7;
link: 0..32767 end;
tracebits = packed record mmm:0..511; nnn: 0..511; ddtflag: 0..1; inputflag: 0..1;
replflag: 0..1; dumpflag: 0..1; detailflag: 0..1; overflag: 0..1 end;
ee = record case 1..4 of
1: (eq: eqtbval);
2: (int: integer);
3: (pts: real);
4: (tr: tracebits)
end;
mm = record case 1..5 of
1: (pts: real);
2: (int: integer);
3: (il: inflnk);
4: (tl: toklnk);
5: (something_else_probably_too)
end;
var mem = array 0..memsize-1 of mm;
eqtb = array 0..eqtbsize-1 of ee;
{{\text The \\{get_next} procedure acts as \TEX's eyes and mouth, as they read and
gobble up source files or stored tokens. The main duty of \\{get_next} is to
input one token, setting \\{curcmd} to the code for the corresponding command
and setting \\{curchar} to the code for the corresponding character. Furthermore,
the value of \\{hashentry} is made nonnegative if and only if the new input token
is a control sequence (and, if so, \\{hashentry} is set to the corresponding
location in \\{eqtb}). Although this procedure has to handle a lot of different
cases, an attempt has been made to keep its inner loop reasonably short and fast.}}
procedure get_next; {{ sends next input token to \\{curcmd} and \\{curchar} }}
label do_get_next, {{ go here to get the next token }}
end_get_next, {{ go here when the next token has been got }}
inner_switch; {{ go here to read the next character }}
var { Locals for \\{get_next} }
begin
do_get_next:
if state <> tokenlist then {{ Reading from an external file }}
{ Input from external file,
\goto\ \\{end_get_next} with paragraph end token if end of file,
\goto\ \\{do_get_next} if no input token found }
else { Input from token list, \goto\ \{do_get_next} if end of list
or if a parameter needs to be expanded };
if { End of alignment entry sensed? } then
{ Insert the $\langle v↓j \rangle$ list and \goto\ \\{do_get_next} };
end_get_next:
end
{ End of align ... } = alignstate = 0 and ((curcmd=tabmrk) or (curcmd=carret))
{ Insert the $\lan ... } =
begin align_insert;
hashentry := -1; {{ this resets \\{hashentry} in case it points to \.{``cr} }}
goto do_get_next
end
{ Input from external file,
\goto\ \\{end_get_next} with paragraph end token if end of file,
\goto\ \\{do_get_next} if no input token found } =
if curbuf < instack_ptr then {{ Current line not empty }}
begin { Read one character of the input };
{ Change state if necessary, and \goto\ \\{innerswitch} if the
current character should be ignored }
end
else begin { Move to next line of file, or
\goto\ \\{end_get_next} with paragraph end token if end of file,
or \goto\ \\{do_get_next} if inserted list just ended };
goto inner_switch
end
{ Read one char ... } =
begin curchar := ord(instack[instack_ptr]);
instack_ptr := instack_ptr + 1;
curcmd := eqtb[curchar+chartype_offset].int
end
{ Change state ... } =
case state + curcmd of
{ Cases where character is ignored }: goto innerswitch;
{ Cases involving an escape character }: { Scan a control sequence };
{ Handle situations involving spaces, braces, changes of state};
others: { Do nothing }
end
{ Cases where character is ignored } = midline+ignore, skipblanks+ignore,
skipblanks+spacer, newline+ignore, newline+spacer
{ Cases involving an escape character } = midline+escape, skipblanks+escape,
newline+escape
{ Do nothing } =
{ Scan a control ... } =
begin control_seq;
with eqtb[hashentry].eq do
begin curcmd_idcmd; curchar_link
end;
state_skipblanks
end
{ Handle situations inv... } =
midline+spacer: { Set \\{skipblanks} state and emit a space };
midline+carret: { Set \\{newline} state and emit a space };
skipblanks+carret: { Set \\{newline} state and \goto\ \\{innerswitch} };
midline+lbrace: alignstate := alignstate + 1;
skipblanks+lbrace, newline+lbrace: { Set \\{midline} state and
increase \\{alignstate} };
midline+rbrace: alignstate := alignstate -1;
skipblanks+rbrace, newline+rbrace: { Set \\{midline} state and
decrease \\{alignstate} };
{ Situations leading to \\{midline} state }: state := midline
{ Set \\{skipblanks} state ... } =
begin state := skipblanks;
curchar := ord(' ')
end
{ Set \\{newline} state and emit ... } =
begin state := newline;
curbuf := instack_ptr; {{ empty the buffer }}
curcmd := spacer;
curchar := ord(' ')
end
{ Set \\{newline} state and \go... } =
begin state := newline;
curbuf := instack_ptr; {{ empty the buffer }}
goto innerswitch
end
{ Situations leading to \\{midline} ... } = skipblanks+mathbr, skipblanks+tabmrk,
skipblanks+macprm, skipblanks+supmrk, skipblanks+submrk, skipblanks+letter,
skipblanks+otherchar, newline+mathbr, newline+tabmrk, newline+macprm,
newline+letter, newline+otherchar
{ Set \\{midline} state and in... } =
begin state := midline;
alignstate := alignstate + 1
end
{ Set \\{midline} state and de... } =
begin state := midline;
alignstate := alignstate - 1
end
{ Move to next line of file, or
\goto\ \\{end_get_next} with paragraph end token if end of file,
or \goto\ \\{do_get_next} if inserted list just ended } =
begin if filename <> 0 then {{ Reading from a character file }}
{ Read next line into input buffer }
else if inptr <> 0 then {{ Input was text inserted by user during error recovery }}
begin popinput; {{ Restore previous input source }}
goto do_get_next
end
else { Input online from terminal into input buffer };
curbuf := inbuf {{ Prepare to scan input buffer }}
end
{ Read next line ... } =
begin inputln; {{ Read current file up to line feed or form feed or eof }}
if eoff then { Process end of file and \goto\ \\{end_get_next} with \\{parend} };
{ Trace the input line if requested };
{ Advance line and page number }
end
{ Process end of file and ... } =
begin write(')'); {{ Show user that the file has been read }}
release(loc); {{ Close the file }}
{ Check if end of page is OK };
popinput; {{ Restore previous status }}
curcmd := parend; curchar := 0;
goto end_get_next
end
{ Check if end of page is OK } =
if page_warning <> OK then page_end_error
{ Trace the input line if requested } =
if eqtb[trace_offset].tr.inputflag then
begin println;
for curbuf := inbuf to instack_ptr-1 do write(instack[curbuf]);
{ Input online ... };
end
{ Input online ... } =
begin println; print('*'); {{ prompt the user }}
inputln;
{ Echo the input on the output file };
{ Define the escape character if the first character has just been read };
end
{ Echo ... } = for curbuf := inbuf to instack_ptr-1 do write(instack[curbuf])
{ Define the escape ... } =
if (escapechar<0) and (ord(instack[inbuf])<>carriage_return) then
begin escapechar := ord(instack[inbuf]);
eqtb[escapechar+chartype_offset].int := escape;
end
{ Advance line and page number } =
with recovery do
if brchar = form_feed then {{ End of page }}
begin info := info + 1; {{ advance page number }}
print(' '); print(info); {{ print progress report for user }}
link := 0; {{ set line number zero }}
{ Check if end of page is OK }
end
else link := link + 1 {{ advance line number }}
{ Input from token list, \goto\ \{do_get_next} if end of list
or if a parameter needs to be expanded } =
if loc <> 0 then {{ Current token list is not empty }}
begin { Read next token from token list};
case curcmd of
0 :{ Process a control sequence token };
outpar : { Insert a macro parameter and \goto\ \\{do_get_next} }
lbrace : alignstate := alignstate + 1;
rbrace : alignstate := alignstate - 1;
others: { Do nothing }
end
else begin { Process end of token list };
popinput; {{ Return to previous level of input }}
goto do_get_next
end
{ Locals for \\{get_next} } +=
t: token; {{ packed token stored in a token list }}
tt: toklnk; {{ packed token and link stored in a token list }}
{ Read next token ... } =
begin tt := mem[loc].tl;
with tt do
begin t := tok; {{ get token to emit }}
loc := link {{ advance to next element of token list }}
curchar := t.chr;
curcmd := t.cmd;
end
end
{ Process a control ... } =
begin hashentry := curchar;
with eqtb[curchar].eq do
begin curcmd := idcmd; curchar := link
end
end
{ Insert a macro par... } =
begin pushinput; {{ Begin a new level of input }}
with recovery do
begin loc := parstack[link + curchar]; {{ Beginning of the parameter }}
info := param;
link := loc; {{ \\{recovery} convention for parameter token list }}
goto do_get_next {{ The state remains equal to \\{tokenlist} }}
end
end
{ Process end of token list } =
case recovery.info of
param, vjlist: { Do nothing };
ujlist: alignstate := 0; {{ $u↓j$ list of an alignment has just ended }}
inserted: dslist(recovery); {{ Destroy a temporarily inserted list }}
others: { Process end of macro body }
end
{ Process end of macro body } =
with recovery do
begin delrclink(info); {{ Dereference the macro body }}
while parptr>link do
begin parptr := parptr-1;
dslist(parstack[parptr]) {{ Destroy a parameter }}
end
end